package com.whfc.mach.manager.impl;

import com.whfc.common.enums.FenceType;
import com.whfc.common.result.PageData;
import com.whfc.common.util.DateUtil;
import com.whfc.common.util.PositionUtil;
import com.whfc.influx.dao.AppMachDataLogDao;
import com.whfc.mach.dao.AppMachMapper;
import com.whfc.mach.dto.AppMachDataLogDTO;
import com.whfc.mach.dto.Gps;
import com.whfc.mach.dto.Oil;
import com.whfc.mach.entity.AppMach;
import com.whfc.mach.entity.AppMachDataLog;
import com.whfc.mach.manager.MachConfigManager;
import com.whfc.mach.manager.MachDataLogManager;
import com.whfc.mach.redis.MachDataRedisDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sun_guodong
 * @description
 * @date 2020-12-02
 */
@Service
public class MachDataLogManagerImpl implements MachDataLogManager {

    @Autowired
    private MachDataRedisDao machDataRedisDao;

    @Autowired
    private AppMachDataLogDao machDataLogDao;

    @Autowired
    private MachConfigManager machConfigManager;

    @Autowired
    private AppMachMapper appMachMapper;

    @Override
    public PageData<AppMachDataLogDTO> getDeviceDataLog(Integer deviceId, Date startTime, Date endTime, Integer pageNum, Integer pageSize) {
        PageData<AppMachDataLogDTO> pageData = machDataLogDao.selectMachDataLogListByDeviceId(deviceId, startTime, endTime, pageNum, pageSize);
        return pageData;
    }

    @Override
    public void addMachDataLog(List<AppMachDataLog> logList) {
        machDataLogDao.batchInsert(logList);
    }

    @Override
    public void addMachDataLogCache(Integer machId, Date date, List<AppMachDataLog> logList) {
        if (logList != null && logList.size() > 0) {
            //当缓存已存在时,才增量更新缓存.
            boolean existsCache = machDataRedisDao.exists(machId, date);
            if (existsCache) {
                machDataRedisDao.addMachDataLog(machId, date, logList);
            }
        }
    }

    @Override
    public void delMachDataLogCache(Integer machId, Date date) {
        machDataRedisDao.delMachData(machId, date);
    }

    @Override
    public List<AppMachDataLogDTO> getMachDataLogCache(Integer machId, Date date) {
        //首次查询,从数据库全量加载当天数据.
        Date startTime = DateUtil.getDateBegin(date);
        Date endTime = DateUtil.getDateEnd(date);
        return this.getMachDataLogCache(machId, date, startTime, endTime);
    }

    @Override
    public List<AppMachDataLogDTO> getMachDataLogCache(Integer machId, Date date, Date startTime, Date endTime) {
        //首次查询,从数据库全量加载当天数据.
        boolean existsCache = machDataRedisDao.exists(machId, date);
        if (!existsCache) {
            Date dateBegin = DateUtil.getDateBegin(date);
            Date dateEnd = DateUtil.getDateEnd(date);
            List<AppMachDataLogDTO> appMachDataLogDTOS = machDataLogDao.selectMachDataLogListByMachId(machId, dateBegin, dateEnd);
            machDataRedisDao.addMachDataLogDTO(machId, date, appMachDataLogDTOS);
        }
        return machDataRedisDao.getMachDataLogDTO(machId, date, startTime, endTime);
    }

    @Override
    public List<Gps> getMachGpsByDate(Integer machId, Date date) {
        return this.getMachGpsByDate(machId, date, true);
    }

    @Override
    public List<Gps> getMachGpsByDate(Integer machId, Date date, boolean isFilter) {
        String polygonWKT = "";
        if (isFilter) {
            AppMach appMach = appMachMapper.selectByPrimaryKey(machId);
            if (appMach != null) {
                polygonWKT = machConfigManager.getPolygonWKT(appMach.getHoldDeptId(), appMach.getMachTypeName());
            }
        }
        final String polygon = polygonWKT;
        List<AppMachDataLogDTO> logDTOS = this.getMachDataLogCache(machId, date);
        return logDTOS.stream()
                .filter(logDTO -> isFilter && PositionUtil.contains(FenceType.POLYGON.value(), polygon, null, logDTO.getLat(), logDTO.getLng()))
                .map(logDTO -> toGps(logDTO))
                .collect(Collectors.toList());
    }

    @Override
    public List<Oil> getMachOilByDate(Integer machId, Date date) {
        List<AppMachDataLogDTO> machDataLogCache = getMachDataLogCache(machId, date);
        return machDataLogCache.stream()
                .filter(logDTO -> logDTO.getOilPos() != null)
                .map(dataLog -> toOil(dataLog))
                .collect(Collectors.toList());
    }

    @Override
    public List<Oil> getMachOilByDate(Integer machId, Date date, Date startTime, Date endTime) {
        List<AppMachDataLogDTO> machDataLogCache = getMachDataLogCache(machId, date, startTime, endTime);
        return machDataLogCache.stream()
                .filter(logDTO -> logDTO.getOilPos() != null)
                .map(dataLog -> toOil(dataLog))
                .collect(Collectors.toList());
    }

    @Override
    public List<Oil> getMachOilByTime(Integer machId, Date startTime, Date endTime) {
        List<AppMachDataLogDTO> appMachDataLogDTOS = machDataLogDao.selectMachDataLogListByMachId(machId, startTime, endTime);
        return appMachDataLogDTOS.stream()
                .filter(logDTO -> logDTO.getOilPos() != null)
                .map(dataLog -> toOil(dataLog))
                .collect(Collectors.toList());
    }

    /**
     * 提取油位信息
     *
     * @param dataLog
     * @return
     */
    private Oil toOil(AppMachDataLogDTO dataLog) {
        Oil oil = new Oil();
        oil.setTime(dataLog.getTime());
        oil.setWorkState(dataLog.getWorkState());
        oil.setOilPos(dataLog.getOilPos());
        oil.setPressure(dataLog.getPressure());
        oil.setWorkState(dataLog.getWorkState());
        oil.setLng(dataLog.getLng());
        oil.setLat(dataLog.getLat());
        oil.setLocation(dataLog.getLocation());
        return oil;
    }

    /**
     * 提取位置信息
     *
     * @param dataLog
     * @return
     */
    private Gps toGps(AppMachDataLogDTO dataLog) {
        Gps gps = new Gps();
        gps.setTime(dataLog.getTime());
        gps.setWorkState(dataLog.getWorkState());
        gps.setLng(dataLog.getLng());
        gps.setLat(dataLog.getLat());
        gps.setLocation(dataLog.getLocation());
        return gps;
    }
}
